﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Drawing;
using System.Windows.Forms;

using ESRI.ArcGIS.Analyst3D;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace SPAS
{
    class Visibility
    {
        static public int Num = 1;

        #region 汤焱编写
        /// <summary>
        /// 可视分析
        /// </summary>
        /// <param name="p"></param>
        /// <param name="rec"></param>
        /// <param name="rasterLayer"></param>
        static public IRasterDataset VisibilityAnalysis(IPoint p, IEnvelope rec, IRasterLayer rasterLayer)
        {
            // 获取临时目录名和文件名
            string workSpacePath = Utils.GetTempDirectory();
            string rasterFileName = "通视分析结果_" + Convert.ToString(Num++) + ".tif";

            // 打开临时工作空间
            IWorkspaceFactory workSpaceFactory = new RasterWorkspaceFactoryClass();
            IWorkspace workSpace = workSpaceFactory.OpenFromFile(workSpacePath, 0);
            IRasterWorkspace2 rasterWorkSpace = workSpace as IRasterWorkspace2;

            // 得到栅格数据集
            IRasterDataset rasterDataset = null;
            try
            {
                rasterDataset = rasterWorkSpace.OpenRasterDataset(rasterFileName);
            }
            catch
            {
            }

            if (rasterDataset != null) // 删除存在的栅格数据集
            {
                IDataset dataset = rasterDataset as IDataset;
                if (dataset.CanDelete())
                    try
                    {
                        dataset.Delete();
                    }
                    catch
                    {
                        MessageBox.Show("删除栅格数据集错误");
                    }
            }
            double cellsizeX = 1.0;
            double cellsizeY = 1.0;

            int colCount = (int)rec.Width + 1;
            int rowCount = (int)rec.Height + 1;

            int numBands = 1;

            IPoint pPoint = rec.LowerLeft;  // 栅格起点（左上角点）
            // 创建栅格数据集
            rasterDataset = rasterWorkSpace.CreateRasterDataset(
                rasterFileName,
                "TIFF",
                pPoint,
                colCount,
                rowCount,
                cellsizeX,
                cellsizeY,
                numBands,
                rstPixelType.PT_UCHAR);

            IRasterBandCollection rasterBands = rasterDataset as IRasterBandCollection;

            IRasterBand rasterBand = rasterBands.Item(0);
            IRasterProps rasterProps = rasterBand as IRasterProps;

            rasterProps.NoDataValue = 255;

            IRaster raster = rasterDataset.CreateDefaultRaster();

            IPnt pnt = new PntClass();
            pnt.SetCoords(cellsizeX, cellsizeY);

            IRaster2 raster2 = raster as IRaster2;
            IRasterEdit rasterEdit = (IRasterEdit)raster2;

            IRasterCursor rasterCursor = raster2.CreateCursorEx(pnt);

            IPixelBlock3 pixelBlock = null;

            bool hasNext = true;

            IPoint p2 = new PointClass();
            while (hasNext)
            {
                pixelBlock = rasterCursor.PixelBlock as IPixelBlock3;

                p2.X = rec.UpperLeft.X + rasterCursor.TopLeft.X + (int)(cellsizeX / 2.0);
                p2.Y = rec.UpperLeft.Y - rasterCursor.TopLeft.Y - (int)(cellsizeY / 2.0);

                System.Array pixels = (System.Array)pixelBlock.get_PixelData(0);
                byte pixelValue = 0;
                if (IsVisible(p, p2, ref rasterLayer))
                {
                    pixelValue = 125;
                }

                for (int i = 0; i < pixelBlock.Width; i++)
                    for (int j = 0; j < pixelBlock.Height; j++)
                        pixels.SetValue(pixelValue, i, j);

                pixelBlock.set_PixelData(0, (System.Array)pixels);

                rasterEdit.Write(rasterCursor.TopLeft, (IPixelBlock)pixelBlock);
                hasNext = rasterCursor.Next();
            }

            System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);

            return rasterDataset;
        }
        #endregion

        #region 周羿编写
        /// <summary>
        /// 两点之间通视性分析
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="rasterLayer"></param>
        /// <returns></returns>
        static public bool IsVisible(IPoint p1, IPoint p2, ref IRasterLayer rasterLayer)
        {
            IRasterSurface rasterSurface = new RasterSurface();
            rasterSurface.PutRaster(rasterLayer.Raster, 0);
            ISurface surface = rasterSurface as ISurface;
            IPoint point = null;
            IPolyline pVpolyline = null;
            IPolyline pInpolyline = null;
            object pRef = 0.13;
            bool pBool = true;

            double pZ1 = surface.GetElevation(p1);
            double pZ2 = surface.GetElevation(p2);
            IPoint pPoint1 = new ESRI.ArcGIS.Geometry.Point();
            pPoint1.Z = pZ1;
            pPoint1.X = p1.X;
            pPoint1.Y = p1.Y;
            IPoint pPoint2 = new ESRI.ArcGIS.Geometry.Point();
            pPoint2.Z = pZ2;
            pPoint2.X = p2.X;
            pPoint2.Y = p2.Y;

            surface.GetLineOfSight(pPoint1, pPoint2, out point, out pVpolyline, out pInpolyline, out pBool, false, false, ref pRef);
            if (pVpolyline != null && pInpolyline == null)
            {
                //p2点可以设站
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 唯一值渲染
        /// </summary>
        /// <param name="rasterLayer"></param>
        /// <param name="cFor0"></param>
        /// <param name="cFor1"></param>
        static public void RasterUniqueRender(IRasterLayer rasterLayer, Color cFor0, Color cFor1)
        {
            IRasterClassifyColorRampRenderer classifyColor = new RasterClassifyColorRampRendererClass();
            IRasterRenderer rasterRender = classifyColor as IRasterRenderer;

            //断点设置
            classifyColor.ClassCount = 2;
            classifyColor.set_Break(0, 120);

            //各个分类的颜色设置
            IFillSymbol Symbol = new SimpleFillSymbolClass() as IFillSymbol;
            Symbol.Color = Utils.ColorToIColor(cFor0);
            classifyColor.set_Symbol(0, Symbol as ISymbol);
            Symbol.Color = Utils.ColorToIColor(cFor1);
            classifyColor.set_Symbol(1, Symbol as ISymbol);
            rasterLayer.Renderer = rasterRender;
        }
        #endregion
    }
}
